#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    mainUIandSlots();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::mainUIandSlots()
{
    ui->treeWidget->expandAll();
    // ---------------- ROI选项 ---------------
    QAction *Rectangle = new QAction("矩形", this);
    QAction *Circle = new QAction("圆形", this);
    QAction *Ellipse = new QAction("椭圆", this);
    QAction *RotateRectangle = new QAction("旋转矩形", this);
    QAction *Polygon = new QAction("多边形", this);

    ui->toolBar->addActions(QList<QAction*>{Rectangle,Circle,Ellipse,RotateRectangle,Polygon});

    connect(Rectangle, &QAction::triggered, this, &MainWindow::createROIRect);
    connect(Circle, &QAction::triggered, this, &MainWindow::createROICircle);
    connect(Ellipse, &QAction::triggered, this, &MainWindow::createROIEllipse);
    connect(RotateRectangle, &QAction::triggered, this, &MainWindow::createROIRotateRect);
    connect(Polygon, &QAction::triggered, this, &MainWindow::createROIPolygon);

    // ---------------- 添加任务窗口 ----------------
    ui->tabWidget->clear();
    TaskWindow *taskwindow = new TaskWindow();
    connect(taskwindow, &TaskWindow::updateTaskItem, this, &MainWindow::updateTaskItem);
    connect(taskwindow, &TaskWindow::updatePicture, this, &MainWindow::updatePicture);
    ui->tabWidget->addTab(taskwindow, QString("任务栏%1").arg(1));
    // ---------------- 添加线程 ----------------
    taskThread *thread = new taskThread();
    connect(thread, &taskThread::updateScene, this, &MainWindow::threadUpdateScene, Qt::QueuedConnection);
    thread->setTaskWindow(taskwindow);
    thread->setNum(0);
    m_taskThreads.append(thread);
    ui->graphicsView->setScene(thread->getScene());
    ui->graphicsView->setmask(&taskwindow->m_mask);

    // ---------------- 图像几任务栏 ----------------
    connect(ui->listWidgetPic, &QListWidget::itemClicked, this, &MainWindow::on_listWidgetPic_itemClicked);
    connect(ui->graphicsView, &MyGraphicsView::updateROI,this, &MainWindow::upROIMask);
    connect(ui->tabWidget, &QTabWidget::currentChanged, this, &MainWindow::TabCurrentChange);

}

void MainWindow::updatePicItem()
{
    ui->listWidgetPic->clear();
    QVector<QPair<QString, QPixmap>>* imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    for(auto pair : *imgs)
    {
        QListWidgetItem* pix = new QListWidgetItem(pair.second, "");
        // pix->setSizeHint(QSize(ui->listWidgetPic->height(), ui->listWidgetPic->height()-25));
        ui->listWidgetPic->addItem(pix);
    }
}

void MainWindow::updateGraphicsView(QPixmap &pixmap)
{
    for(auto item : ui->graphicsView->scene()->items())
    {
        QGraphicsPixmapItem* pixmapItem = dynamic_cast<QGraphicsPixmapItem*>(item);
        if(pixmapItem)
        {
            pixmapItem->setPixmap(pixmap);
        }
    }
    // ui->graphicsView->fitInView(ui->graphicsView->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);   // 图片自适应
    ui->graphicsView->setDragMode(QGraphicsView::DragMode::ScrollHandDrag);  // 设置图元可以拖拉
}

void MainWindow::on_actionOpen_triggered()
{
    QStringList files = QFileDialog::getOpenFileNames(this, "选择图片", "", "Image (*.png *.jpg)");
    if(files.isEmpty())
        return ;

    // 线程加入图片资源
    QVector<QPair<QString, QPixmap>>* imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    imgs->clear();
    imgs->reserve(files.size());

    for (int i = 0; i < files.size(); ++i)
    {
        imgs->append(qMakePair(files[i], QPixmap(files[i])));
    }
    qDebug() << "imgs size :" << imgs->size();
    // 更新场景，场景加入第一张图片
    ui->graphicsView->scene()->clear();
    QGraphicsPixmapItem* item = new QGraphicsPixmapItem(imgs->front().second);
    ui->graphicsView->scene()->addItem(item);
    ui->graphicsView->fitInView(ui->graphicsView->scene()->itemsBoundingRect(), Qt::KeepAspectRatioByExpanding);

    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    // 刷新掩码矩阵
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
    // ------------  暂存图片 ----------------
    if(!imgs->empty())
    {
        taskwindow->m_pic = (*imgs)[0].second.copy();
        taskwindow->m_tmpPic = taskwindow->m_pic.copy();
    }

    // 给listWidget添加图片，即缩略图
    updatePicItem();
}

void MainWindow::on_actionSave_triggered()
{
    if(ui->graphicsView->items().empty())
    {
        QMessageBox::warning(this, "警告", "没有文件");
        return ;
    }
    QGraphicsPixmapItem *pixmapItem = nullptr;
    QPixmap pixmap;
    for (int i = 0; i < ui->graphicsView->items().size(); ++i)
    {
        pixmapItem = dynamic_cast<QGraphicsPixmapItem*>(ui->graphicsView->items().at(i));
        if(pixmapItem)
        {
            pixmap = pixmapItem->pixmap();
        }
    }

    if(!pixmap.isNull())
    {
        auto *imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
        if(!imgs->empty())
        {
            int m_index = m_taskThreads[ui->tabWidget->currentIndex()]->getIndex();
            pixmapItem->pixmap().save((*imgs)[m_index].first);
            (*imgs)[m_index].second = pixmap.copy();
            QMessageBox::information(this, "success", "文件保存成功");

            // 更新缩略图展示列表
            QListWidgetItem* item = ui->listWidgetPic->item(m_index);
            item->setIcon(QIcon(pixmap));
            // QIcon icon(pixmap);
        }
        else
            QMessageBox::warning(this, "警告", "No file select.");
    }
}

void MainWindow::on_actionSaveAs_triggered()
{
    if(ui->graphicsView->items().empty())
    {
        QMessageBox::warning(this, "Warning", "无法保存，因为没有打开的图");
        return;
    }

    QString file_name = QFileDialog::getSaveFileName(this, "SaveAS", "", "Images(*.png *.jpg");

    if(!file_name.isEmpty())
    {
        QFile image_file(file_name);
        if(image_file.open(QIODevice::WriteOnly))
        {
            for(QGraphicsItem *item : ui->graphicsView->scene()->items())
            {
                QGraphicsPixmapItem *pixmapItem = dynamic_cast<QGraphicsPixmapItem*>(item);
                if(pixmapItem)
                {
                    pixmapItem->pixmap().save(&image_file, QFileInfo(file_name).suffix().toUtf8().constData());
                    image_file.close();
                    QMessageBox::information(this, "success", "文件保存成功");
                    return;
                }
            }
            QMessageBox::warning(this, "fail", "文件保存失败");
        }
    }
}

void MainWindow::on_actionImport_triggered()
{
    QJsonDocument doc;
    int m_index = ui->tabWidget->currentIndex();
    taskThread *taskthread = m_taskThreads[m_index];
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());

    // 打开Json配置文件
    QString filepath = QFileDialog::getOpenFileName(this, "openJsonFile", "",tr("(*.json)"));
    if(!filepath.isEmpty())
    {
        QFile file(filepath);
        if(file.open(QIODevice::ReadOnly))
        {
            // ------ 删除所有资源 ----------
            taskthread->setIndex(taskthread->getIndex());
            taskthread->getImgs()->clear();                 // 先清楚当前线程已存在的图片成员
            ui->graphicsView->scene()->clear();             //
            taskwindow->m_items.clear();
            taskwindow->clear();

            doc = QJsonDocument::fromJson(file.readAll());
            QJsonObject root = doc.object();

            // 生成图形
            QJsonArray picArray = root.value("PIC").toArray();
            taskthread->setIndex(picArray[0].toInt());
            for (int i = 1; i < picArray.size(); ++i)
            {
                QPixmap pixmap = QPixmap(picArray[i].toString());
                if(pixmap.isNull())
                {
                    QMessageBox::warning(this, "警告", "原图路劲失效，导入失败！");
                    return;
                }
                taskthread->getImgs()->push_back(qMakePair(picArray[i].toString(), pixmap));
            }
            QPixmap pixmap = QPixmap((*taskthread->getImgs())[taskthread->getIndex()].first);
            QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);                    // 更新场景，场景加入选中的那张图片
            ui->graphicsView->scene()->addItem(item);
            ui->graphicsView->fitInView(item->boundingRect(), Qt::KeepAspectRatio);         // 窗口自适应
            taskwindow->m_pic = taskwindow->m_tmpPic = pixmap.copy();                       // 初始化图片源
            taskwindow->m_mask = Mat::ones(pixmap.height(), pixmap.width(), CV_8UC1)*255;   // 初始化掩码
            updatePicItem();                                                                // 更新缩略图图像

            // 添加任务
            QJsonArray TaskItemArray = root.value("TaskItem").toArray();    // Task对象
            for(int i = 0; i < TaskItemArray.size(); i++)
            {
                QJsonObject TaskItem = TaskItemArray.at(i).toObject();      // 任务对象
                auto task = AbstractFactory::createTaskItem(TaskItem.value("name").toString());     // 1.创建任务对象
                if(task)
                {
                    task->setWindowParam(&taskwindow->m_pic, &taskwindow->m_tmpPic, &taskwindow->m_mask);
                    task->setClick(TaskItem.value("isCheck").toBool());     // 设置了就会进行任务调度
                    QJsonObject param = TaskItem.value("param").toObject();     // 用于存储任务参数
                    QMap<QString, QString> mparam;
                    for (auto key : param.keys())
                    {
                        mparam[key] = param.value(key).toString();              // 2. 设置任务参数
                    }
                    task->setParam(mparam);
                    taskwindow->m_items.append(task);                           // 3. 任务对象里添加
                    updateTaskItem(taskwindow->m_items.size()-1);               // 4. 场景里添加
                }
            }

            // 生成ROI图形+掩码矩阵
            QJsonArray ROIItemArray = root.value("ROI").toArray();
            for (int i = 0; i < ROIItemArray.size(); ++i)
            {
                QJsonObject ROIItem;    // ROI对象
                QJsonObject ROIrect;    // 用于存储矩形参数
                QJsonArray ROIpoint;    // 用于存储多边形点集合
                ROIItem = ROIItemArray.at(i).toObject();
                switch(ROIItem.value("type").toInt())
                {
                case ROIShape::RECTANGE:
                {
                    ROIrect = ROIItem.value("shape").toObject();
                    QRectF tmp = QRect(ROIrect.value("x").toDouble(),
                                      ROIrect.value("y").toDouble(),
                                      ROIrect.value("width").toDouble(),
                                      ROIrect.value("height").toDouble());
                    Rectangle *rect = new Rectangle(tmp);
                    rect->setboundingRect(tmp);
                    connect(rect, &ROI::upROIMask, this, &MainWindow::upROIMask);       // 更新编码
                    ui->graphicsView->scene()->addItem(rect);
                    break;
                }
                case ROIShape::ROTATERECTANGE:
                {
                    ROIrect = ROIItem.value("shape").toObject();
                    QRectF tmp = QRect(ROIrect.value("x").toDouble(),
                                       ROIrect.value("y").toDouble(),
                                       ROIrect.value("width").toDouble(),
                                       ROIrect.value("height").toDouble());
                    RotateRectangle *rect = new RotateRectangle(tmp);
                    QString StringTrans = ROIrect.value("transform").toString();
                    QTransform transform;
                    QStringList values = StringTrans.split(",");
                    qreal m11 =values[0].toDouble();
                    qreal m12 =values[1].toDouble();
                    qreal m13 =values[2].toDouble();
                    qreal m21 =values[3].toDouble();
                    qreal m22 =values[4].toDouble();
                    qreal m23 =values[5].toDouble();
                    qreal m31 =values[6].toDouble();
                    qreal m32 =values[7].toDouble();
                    qreal m33 =values[8].toDouble();
                    transform.setMatrix(m11, m12, m13, m21, m22, m23, m31, m32, m33);

                    rect->setboundingRect(tmp, transform);
                    connect(rect, &ROI::upROIMask, this, &MainWindow::upROIMask);       // 更新掩码
                    ui->graphicsView->scene()->addItem(rect);
                    break;
                }
                case ROIShape::ELLIPSE:
                {
                    ROIrect = ROIItem.value("shape").toObject();
                    QRectF tmp = QRect(ROIrect.value("x").toDouble(),
                                       ROIrect.value("y").toDouble(),
                                       ROIrect.value("a").toDouble(),
                                       ROIrect.value("b").toDouble());
                    Ellipse *ellipse = new Ellipse(tmp);
                    ellipse->setboundingRect(tmp);
                    connect(ellipse, &ROI::upROIMask, this, &MainWindow::upROIMask);
                    ui->graphicsView->scene()->addItem(ellipse);
                    break;
                }
                case ROIShape::CIRCLE:
                {
                    ROIrect = ROIItem.value("shape").toObject();
                    QRectF tmp = QRect(ROIrect.value("x").toDouble(),
                                       ROIrect.value("y").toDouble(),
                                       ROIrect.value("a").toDouble(),
                                       ROIrect.value("a").toDouble());
                    Circle *circle = new Circle(tmp);
                    circle->setboundingRect(tmp);
                    connect(circle, &ROI::upROIMask, this, &MainWindow::upROIMask);
                    ui->graphicsView->scene()->addItem(circle);
                    break;
                }
                case ROIShape::POLYGON:
                {
                    QPolygonF polygonf;
                    ROIpoint = ROIItem.value("polygon").toArray();
                    for(int i = 0; i < ROIpoint.size(); ++i)
                    {
                        QJsonObject tmp = ROIpoint.at(i).toObject();
                        QPointF point(tmp.value("x").toDouble(), tmp.value("y").toDouble());
                        polygonf << point;
                    }
                    Polygon *polygon = new Polygon(polygonf);
                    connect(polygon, &ROI::upROIMask, this, &MainWindow::upROIMask);
                    ui->graphicsView->scene()->addItem(polygon);
                    break;
                }
                }
            }
            ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
            QMessageBox::information(this, "提示", "导入成功！");
            taskwindow->updateTasks(taskthread->getNum());
        }
        else
            QMessageBox::warning(this, "提示", "导入失败！");
    }
}

void MainWindow::on_actionExport_triggered()
{
    int m_index = ui->tabWidget->currentIndex();
    taskThread *taskthread = m_taskThreads[m_index];
    TaskWindow* taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());

    QJsonObject root;
    // 图片
    QJsonArray picArray;
    picArray.append(taskthread->getIndex());    // 保存当前选择的图片下标
    for (int i = 0; i < taskthread->getImgs()->size(); ++i)
    {
        picArray.append(taskthread->getImgs()->at(i).first);
    }
    root.insert("PIC", picArray);       // 保存当前选择的图片路径

    // ROI
    QJsonArray ROIItemArray;
    for (int i = 0; i < ui->graphicsView->scene()->items().size(); ++i)
    {
        QGraphicsItem* Gitem = ui->graphicsView->scene()->items().at(i);
        if(Gitem->type() == QGraphicsPixmapItem::Type)
            continue;

        ROI* item = dynamic_cast<ROI*>(Gitem);
        QJsonObject ROIItem;    // 用于ROI对象
        QJsonObject ROIrect;    // 用于存储矩形参数
        QJsonArray ROIpoint;    // 用于存储多边形的点
        switch (item->Type())
        {
        case ROIShape::RECTANGE:
        {
            ROIrect.insert("x", item->boundingRect().x());
            ROIrect.insert("y", item->boundingRect().y());
            ROIrect.insert("width", item->boundingRect().width());
            ROIrect.insert("height", item->boundingRect().height());
            break;
        }
        case ROIShape::ROTATERECTANGE:
        {
            RotateRectangle* item = dynamic_cast<RotateRectangle*>(Gitem);
            ROIrect.insert("x", item->boundingRect().x());
            ROIrect.insert("y", item->boundingRect().y());
            ROIrect.insert("width", item->boundingRect().width());
            ROIrect.insert("height", item->boundingRect().height());
            ROIrect.insert("transform", QString("%1, %2, %3, %4, %5, %6, %7, %8, %9")
                           .arg(item->getQTransform().m11())
                           .arg(item->getQTransform().m12())
                           .arg(item->getQTransform().m13())
                           .arg(item->getQTransform().m21())
                           .arg(item->getQTransform().m22())
                           .arg(item->getQTransform().m23())
                           .arg(item->getQTransform().m31())
                           .arg(item->getQTransform().m32())
                           .arg(item->getQTransform().m33())
                           );
            break;
        }
        case ROIShape::ELLIPSE:
        case ROIShape::CIRCLE:
        {
            ROIrect.insert("x", item->boundingRect().x());
            ROIrect.insert("y", item->boundingRect().y());
            ROIrect.insert("a", item->boundingRect().width());
            ROIrect.insert("b", item->boundingRect().height());
            break;
        }
        case ROIShape::POLYGON:
        {
            Polygon* item = dynamic_cast<Polygon*>(Gitem);
            QPolygonF polygon;
            item->getPolygon(polygon);
            for(auto pointf: polygon)
            {
                QJsonObject ROIrect;
                ROIrect.insert("x", pointf.x());
                ROIrect.insert("y", pointf.y());
                ROIpoint.append(ROIrect);
            }
            break;
        }
        }
        ROIItem.insert("type", item->Type());
        if(item->Type() == ROIShape::POLYGON)
            ROIItem.insert("polygon", ROIpoint);
        else
            ROIItem.insert("shape", ROIrect);

        ROIItemArray.append(ROIItem);
    }
    root.insert("ROI", ROIItemArray);

    // TaskItem
    QJsonArray TaskItemArray;       // Task对象
    for(auto sTask : taskwindow->m_items)
    {
        TaskItem* task = sTask;
        QJsonObject TaskItem;   // 任务对象

        TaskItem.insert("isCheck", task->isClicked());
        for (int i = 0; i < task->toJson().size(); ++i)
        {
            QJsonObject tmp = task->toJson().at(i).toObject();
            for(auto key : tmp.keys())
                TaskItem.insert(key, tmp.value(key));
        }
        TaskItemArray.append(TaskItem);
    }
    root.insert("TaskItem", TaskItemArray);

    QJsonDocument doc;
    doc.setObject(root);

    // 写文件
    QString filePath = QFileDialog::getSaveFileName(this, "saveAsJson", "", tr("(*.json)"));
    if(!filePath.isEmpty())
    {
        QFile file(filePath);
        if(file.open(QIODevice::WriteOnly))
        {
            file.write(doc.toJson());
            file.close();
            QMessageBox::information(this, "success", "文件保存成功");
        }
        else
        {
            QMessageBox::warning(this, "警告", "文件打开失败");
        }
    }
}

void MainWindow::on_listWidgetPic_itemClicked(QListWidgetItem *item)
{
    taskThread* thread = m_taskThreads[ui->tabWidget->currentIndex()];  // 当前线程
    if(thread->getImgs()->empty())
        return ;
    // ----- 显示图片 -----
    int index = ui->listWidgetPic->row(item);
    qDebug() << "pic编号" << index;
    for (int i = 0; i < ui->graphicsView->items().size(); ++i)
    {
        QGraphicsPixmapItem *pixmapItem = dynamic_cast<QGraphicsPixmapItem*>(ui->graphicsView->scene()->items().at(i));
        if(pixmapItem)
        {
            pixmapItem->setPixmap((*thread->getImgs())[index].second);
            break;
        }
    }
    ui->graphicsView->fitInView(ui->graphicsView->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);   // 图片自适应

    TaskWindow* taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    // ------------------- 暂存图片 -----------------------
    taskwindow->m_pic = (*thread->getImgs())[index].second.copy();
    taskwindow->m_tmpPic = (*thread->getImgs())[index].second.copy();
    thread->setIndex(index);
    // ------------------- 刷新掩码矩阵 ------------------
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
    // ------------------- 执行任务 -------------------
    taskwindow->updateTasks(thread->getNum());
}


// ------------------- ROI ------------------------
void MainWindow::createROIRect()
{
    auto imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    if(imgs->empty())
    {
        QMessageBox::warning(this, "警告", "没有插入图片");
        return;
    }
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    ROI* rect = new Rectangle();
    connect(rect, &ROI::upROIMask, this, &MainWindow::upROIMask);
    ui->graphicsView->scene()->addItem(rect);
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);

}

void MainWindow::createROICircle()
{
    auto imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    if(imgs->empty())
    {
        QMessageBox::warning(this, "警告", "没有插入图片");
        return;
    }
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());

    ROI* circle = new Circle();
    connect(circle, &ROI::upROIMask, this, &MainWindow::upROIMask);
    ui->graphicsView->scene()->addItem(circle);
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
}

void MainWindow::createROIEllipse()
{
    auto imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    if(imgs->empty())
    {
        QMessageBox::warning(this, "警告", "没有插入图片");
        return;
    }
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());

    ROI* ellipse = new Ellipse();
    connect(ellipse, &ROI::upROIMask, this, &MainWindow::upROIMask);
    ui->graphicsView->scene()->addItem(ellipse);
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
}

void MainWindow::createROIRotateRect()
{
    auto imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    if(imgs->empty())
    {
        QMessageBox::warning(this, "警告", "没有插入图片");
        return;
    }
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());

    ROI* rect = new RotateRectangle();
    connect(rect, &ROI::upROIMask, this, &MainWindow::upROIMask);
    ui->graphicsView->scene()->addItem(rect);
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
}

void MainWindow::createROIPolygon()
{
    auto imgs = m_taskThreads[ui->tabWidget->currentIndex()]->getImgs();
    if(imgs->empty())
    {
        QMessageBox::warning(this, "警告", "没有插入图片");
        return;
    }

    if(!ui->graphicsView->getDraw())
    {
        ui->graphicsView->setDraw(true);    // 设置可以画多边形
        QMessageBox::information(this, "提示", "左键开始右键结束");
        return;
    }
}

void MainWindow::upROIMask()
{
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
    taskwindow->updateTasks(ui->tabWidget->currentIndex());
    // imshow("666", taskwindow->m_mask);  // TODO:m_mask为空
}

// ------------------  线程  ------------------------
void MainWindow::threadUpdateScene(int num)
{
    if(num != ui->tabWidget->currentIndex())
    {
        qDebug() << num << "线程场景不符，退出";
        return;
    }

    taskThread* thread = m_taskThreads[ui->tabWidget->currentIndex()];
    auto *imgs = thread->getImgs();
    QGraphicsScene *scene = thread->getScene();
    ui->graphicsView->setScene(scene);

    for (int i = 0; i < scene->items().size(); ++i)
    {
        QGraphicsPixmapItem* pixmap = dynamic_cast<QGraphicsPixmapItem*>(scene->items().at(i));
        if(pixmap)
        {
            pixmap->setPixmap((*imgs)[thread->getIndex()].second);
            break;
        }
    }

    // 更新缩略图，掩码，图像
    if(thread->getImgs()->empty())
    {
        return;
    }
    ui->listWidgetPic->item(thread->getIndex())->setSelected(true);  // 设置当前图像被选中

    // 暂存图片
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    taskwindow->m_pic = (*thread->getImgs())[thread->getIndex()].second.copy();
    taskwindow->m_tmpPic = taskwindow->m_pic.copy();

    // 刷新掩码矩阵
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
}

void MainWindow::on_dealBtn_clicked()
{
    TaskWindow* taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    if(!taskwindow->m_pic.isNull())
    {
        for(auto &item : taskwindow->m_items)
        {
            (*item).setClick(true);
        }
        taskwindow->updateTasks(ui->tabWidget->currentIndex());
    }
    else
        QMessageBox::warning(this, "警告", "没有导入图片");
}

void MainWindow::on_cancelBtn_clicked()
{
    TaskWindow* taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    if(!taskwindow->m_pic.isNull())
    {
        for(auto &item : taskwindow->m_items)
        {
            (*item).setClick(false);
        }
        taskwindow->updateTasks(ui->tabWidget->currentIndex());
    }
    else
        QMessageBox::warning(this, "警告", "没有导入图片");
}

void MainWindow::on_addTasklistBtn_clicked()
{
    static int index = 1;
    QString tabName = QString("任务栏%1").arg(++index);
    TaskWindow* taskwindow = new TaskWindow();
    connect(taskwindow, &TaskWindow::updateTaskItem, this, &MainWindow::updateTaskItem);  // 添加任务
    connect(taskwindow, &TaskWindow::updatePicture, this, &MainWindow::updatePicture);  // 更新图像
    ui->tabWidget->addTab(taskwindow, tabName);

    // 新建线程
    taskThread *thread = new taskThread();
    connect(thread, &taskThread::updateScene, this, &MainWindow::threadUpdateScene, Qt::QueuedConnection);
    thread->setTaskWindow(taskwindow);
    thread->setNum(ui->tabWidget->count()-1);
    qDebug() << "线程" << thread->getNum() << "创建";
    m_taskThreads.append(thread);
}

void MainWindow::on_delTasklistBtn_clicked()  // 删除时要阻塞所有线程，执行完再唤醒所有线程 [解决：空指针判断即可]
{
    if(ui->tabWidget->count() == 1)
    {
        QMessageBox::warning(this, "警告", "最少保留一个任务栏");
        return;
    }
    int curIndex = ui->tabWidget->currentIndex();
    ui->tabWidget->removeTab(ui->tabWidget->currentIndex());  // 删除完这个标签会自动调用“on_tabWidge_currentChange”
    if(curIndex == ui->tabWidget->count())
    {
        m_taskThreads[curIndex]->terminate();
        m_taskThreads.removeAt(curIndex);
        qDebug() << curIndex << "线程退出";
    }
    else
    {
        m_taskThreads[ui->tabWidget->currentIndex()]->terminate();
        m_taskThreads.removeAt(ui->tabWidget->currentIndex());
        qDebug() << ui->tabWidget->currentIndex() << "线程退出";
    }

    for (int i = 0; i < ui->tabWidget->count(); ++i)  // 更新线程编号
    {
        m_taskThreads[i]->setNum(i);
    }
    TabCurrentChange(ui->tabWidget->currentIndex());  // 要放后面，因为QListWidget要及时更新
}

void MainWindow::on_loopBtn_clicked()
{
    taskThread* thread = m_taskThreads[ui->tabWidget->currentIndex()];

    if(thread->getImgs()->size() <= 0)
    {
        QMessageBox::warning(this, "警告", "没有图片");
        return ;
    }
    if(thread)
    {
        thread->setFlag(true);
        thread->setDeal(false);
        thread->start();
    }
}

void MainWindow::on_loopCancelBtn_clicked()
{
    taskThread* thread = m_taskThreads[ui->tabWidget->currentIndex()];
    if(thread)
    {
        thread->setFlag(false);
    }
}

void MainWindow::TabCurrentChange(int index)
{
    if(m_taskThreads.empty() || index < 0)
        return;
    qDebug() << "任务栏" << index;
    taskThread* thread = m_taskThreads[index]; // 更换场景
    qDebug() << "目前是：线程" << thread->getNum();
    ui->graphicsView->setScene(thread->getScene());
    TaskWindow* taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    ui->graphicsView->setmask(&taskwindow->m_mask);
    ui->graphicsView->fitInView(ui->graphicsView->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);

    // 更新缩略图，掩码，图像
    updatePicItem();
    if(thread->getImgs()->empty())
        return;
    // 暂存图片
    taskwindow->m_pic = (*thread->getImgs())[thread->getIndex()].second.copy();
    taskwindow->m_tmpPic = (*thread->getImgs())[thread->getIndex()].second.copy();
    // 更新掩码矩阵
    ROI::setMask(ui->graphicsView->scene()->items(), taskwindow->m_mask);
}

// ------------------  UI更新  ----------------------
void MainWindow::updateTaskItem(int index)
{
    qDebug() << "下标为" << index << "的任务";
    TaskWindow* taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->currentWidget());
    taskwindow->setSpacing(5);
    auto task = taskwindow->m_items[index];
    QListWidgetItem* item = new QListWidgetItem();
    item->setSizeHint(QSize(task->width(),task->height()));
    taskwindow->insertItem(index, item);    // 将新任务对象插入所选行
    taskwindow->setItemWidget(item, task);

    connect(task, &TaskItem::updateTask, m_taskThreads[ui->tabWidget->currentIndex()], &taskThread::dealTask);
    connect(task, &TaskItem::updatePicture, this, [=]{
        updateGraphicsView(taskwindow->m_pic);
    });
}

void MainWindow::updatePicture(bool click, int Num)
{
    if(Num == -1)
        Num = ui->tabWidget->currentIndex();    // 表示当前线程，这里是为了右键菜单栏的更新设置的
    TaskWindow *taskwindow = dynamic_cast<TaskWindow*>(ui->tabWidget->widget(Num));
    if(taskwindow == nullptr) return;           // 预防线程同步间数据不一致出现的nullptr

#if 0
    if(taskwindow->m_items.size() > 0)
    {
        if(click && Num == ui->tabWidget->currentIndex())
        {
            qDebug() << '1';
            updateGraphicsView(taskwindow->m_pic);
            return ;
        }
    }
    taskThread* thread = m_taskThreads[Num];
    if(click == false && !thread->getImgs()->empty()) // 还原成原来的图片
    {
        taskwindow->m_pic = (*thread->getImgs())[thread->getIndex()].second.copy();
        taskwindow->m_tmpPic = (*thread->getImgs())[thread->getIndex()].second.copy();
    }
    if(click == true && Num == ui->tabWidget->currentIndex())
    {
        // QLabel* label = new QLabel("updatePicture false");
        // label->setPixmap(taskwindow->m_pic);
        // label->show();
        qDebug() << '2';
        updateGraphicsView(taskwindow->m_pic);
    }
#endif
    taskThread* thread = m_taskThreads[Num];
    if(taskwindow->m_items.size() > 0 && Num == ui->tabWidget->currentIndex())
    {
        if(click)  // 让主UI更新界面
        {
            qDebug() << "------------- true -----------------";
            updateGraphicsView(taskwindow->m_pic);
        }
        else // 还原成原来图片
        {
            qDebug() << "------------- fasle -----------------";
            if(!thread->getImgs()->empty())
            {
                taskwindow->m_pic = (*thread->getImgs())[thread->getIndex()].second.copy();
                taskwindow->m_tmpPic = (*thread->getImgs())[thread->getIndex()].second.copy();
            }
        }
    }
}


